//
//  ScanViewController.swift
//  AccountingHelper
//
//  Created by HuangZe on 2025/5/19.
//

import UIKit
import AVFoundation
import SnapKit

class ScanViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
    // MARK: - 属性
    private var captureSession: AVCaptureSession!
    private var previewLayer: AVCaptureVideoPreviewLayer!
    private var maskLayer: CAShapeLayer!  // 添加遮罩层
    
    private var isAnimating = false // 添加标志来跟踪动画状态
    private var scanImageView: UIImageView! // 用于显示动画图片
    private var scanLineAnimation: CABasicAnimation!
    
    // MARK: - 视图生命周期
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        setupCamera()
        setupScanImageView() // 扫描动画线
        setupPhotoButton()
        
        // 提前添加照片输出
        let photoOutput = AVCapturePhotoOutput()
        if captureSession.canAddOutput(photoOutput) {
            captureSession.addOutput(photoOutput)
        }
        
        // 添加应用状态监听
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(appwillEnterForeground),
            name: UIApplication.willEnterForegroundNotification,
            object: nil
        )
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(appDidEnterForeground),
            name: UIApplication.didEnterBackgroundNotification,
            object: nil
        )
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        stopCaptureSession()
        previewLayer?.removeFromSuperlayer()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        startRunningAndAnimation()
    }
    
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .portrait // 只支持竖屏
    }
    
    // MARK: - 应用状态监听
    @objc private func appwillEnterForeground() {
        startRunningAndAnimation()
    }
    
    @objc private func appDidEnterForeground() {
        stopCaptureSession()
        captureSession?.stopRunning()
    }
    
    // 在deinit中移除监听
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
    // MARK: - UI设置
    private func setupCameraPermissionDenied() {
        view.backgroundColor = .black
        let noPermissionView = createNotPermissionView()
        
        noPermissionView.backgroundColor = .darkGray
        noPermissionView.layer.cornerRadius = 14 // 可以根据需要调整圆角半径
        noPermissionView.layer.masksToBounds = true
        view.addSubview(noPermissionView)
        
        noPermissionView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.width.equalTo(300)
        }
    }
    
    private func createNotPermissionView() -> UIView {
        let view = UIView()
        
        // 添加图片
        let warningImage = UIImage(named: "waringImg")
        let warningImageView = UIImageView(image: warningImage)
        warningImageView.contentMode = .scaleAspectFit
        view.addSubview(warningImageView)
        
        // 添加 label
        let messageLabel = UILabel()
        messageLabel.text = "无法扫码发票，请前往「设置 > 微信」打开相机权限"
        messageLabel.numberOfLines = 0
        messageLabel.textAlignment = .center
        messageLabel.textColor = .white
        view.addSubview(messageLabel)
        
        // 添加前往设置按钮
        let settingsButton = UIButton(type: .system)
        settingsButton.setTitle("前往设置", for: .normal)
        settingsButton.titleLabel?.font = UIFont.systemFont(ofSize: 16)
        settingsButton.setTitleColor(.black, for: .normal)
        settingsButton.backgroundColor = .white
        settingsButton.layer.cornerRadius = 20
        settingsButton.clipsToBounds = true
        settingsButton.addTarget(self, action: #selector(openSettings), for: .touchUpInside)
        view.addSubview(settingsButton)
        
        // 设置约束
        warningImageView.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(20)
            make.centerX.equalToSuperview()
            make.size.equalTo(45)
        }
        
        messageLabel.snp.makeConstraints { make in
            make.top.equalTo(warningImageView.snp.bottom).offset(25)
            make.leading.trailing.equalToSuperview().inset(20)
        }
        
        settingsButton.snp.makeConstraints { make in
            make.top.equalTo(messageLabel.snp.bottom).offset(30)
            make.centerX.equalToSuperview()
            make.size.equalTo(CGSize(width: 140, height: 40))
            make.bottom.equalToSuperview().offset(-30)
        }
        
        return view
    }
    
    @objc private func openSettings() {
        if let url = URL(string: UIApplication.openSettingsURLString) {
            UIApplication.shared.open(url)
        }
    }
    
    private func setupScanImageView() {
        guard let scanImage = UIImage(named: "Scanline") else {
            print("未能加载扫描图片")
            return
        }
        
        scanImageView = UIImageView(image: scanImage)
        scanImageView.contentMode = .scaleToFill
        view.addSubview(scanImageView)
        
        // 使用 SnapKit 设置约束
        scanImageView.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.width.equalToSuperview().multipliedBy(0.8) // 宽度为父视图的80%
            make.height.equalTo(scanImage.size.height)
            make.top.equalToSuperview().offset(view.bounds.height * 0.2)
        }
    }
    
    private func setupPhotoButton() {
        let photoButton = UIButton(type: .system)
        photoButton.backgroundColor = UIColor.systemBlue.withAlphaComponent(0.8)
        photoButton.setTitleColor(.white, for: .normal)
        photoButton.layer.cornerRadius = 8
        photoButton.addTarget(self, action: #selector(takePhoto), for: .touchUpInside)
        
        let config = UIImage.SymbolConfiguration(pointSize: 16, weight: .medium)
        let cameraIcon = UIImage(systemName: "camera", withConfiguration: config)
        
        var configuration = UIButton.Configuration.plain()
        configuration.image = cameraIcon
        configuration.title = "拍照识别"
        configuration.imagePadding = 8
        configuration.baseForegroundColor = .white
        photoButton.configuration = configuration
        
        view.addSubview(photoButton)
        photoButton.snp.makeConstraints { make in
            make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom).offset(-20)
            make.centerX.equalToSuperview()
            make.width.equalTo(150)
            make.height.equalTo(44)
        }
    }
    
    
    // MARK: - 相机配置 / 权限
    private func setupCamera() {
        captureSession = AVCaptureSession()
        // 设置更高的会话预设
        captureSession.sessionPreset = .photo
        
        // 检查相机设备是否可用
        guard let videoDevice = AVCaptureDevice.default(for: .video) else {
            print("无法访问相机设备")
            return
        }
        
        // 创建视频输入
        guard let videoInput = try? AVCaptureDeviceInput(device: videoDevice),
              captureSession.canAddInput(videoInput) else {
            print("无法创建视频输入")
            return
        }
        
        captureSession.addInput(videoInput)
        
        // 创建元数据输出
        let metadataOutput = AVCaptureMetadataOutput()
        guard captureSession.canAddOutput(metadataOutput) else {
            print("无法创建元数据输出")
            return
        }
        
        captureSession.addOutput(metadataOutput)
        metadataOutput.setMetadataObjectsDelegate(self, queue: .main)
        
        // 设置可识别的码类型
        let availableTypes = metadataOutput.availableMetadataObjectTypes
        let desiredTypes: [AVMetadataObject.ObjectType] = [.qr, .code128, .pdf417, .aztec]
        metadataOutput.metadataObjectTypes = desiredTypes.filter { availableTypes.contains($0) }
        
        // 设置预览层
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer.frame = view.layer.bounds
        previewLayer.videoGravity = .resizeAspectFill
        view.layer.addSublayer(previewLayer)
        
        // 设置扫描区域
        metadataOutput.rectOfInterest = previewLayer.metadataOutputRectConverted(fromLayerRect: view.bounds)
    }
    
    @objc private func takePhoto() {
        guard let captureSession = captureSession else { return }
        
        // 创建照片输出
        guard let photoOutput = captureSession.outputs.first(where: { $0 is AVCapturePhotoOutput }) as? AVCapturePhotoOutput else {
            print("无法找到照片输出")
            return
        }
        
        // 配置照片设置
        let settings = AVCapturePhotoSettings()
        // 设置照片质量（兼容新旧iOS版本）
        if #available(iOS 16.0, *) {
            // 获取设备支持的最大尺寸
            if let videoDevice = captureSession.inputs.first(where: { $0 is AVCaptureDeviceInput }) as? AVCaptureDeviceInput {
                let activeFormat = videoDevice.device.activeFormat
                let supportedDimensions = activeFormat.supportedMaxPhotoDimensions
                if let firstDimension = supportedDimensions.first {
                    settings.maxPhotoDimensions = firstDimension
                }
            }
        } else {
            // 使用旧属性
            settings.isHighResolutionPhotoEnabled = true
        }
        
        // 开始拍照
        photoOutput.capturePhoto(with: settings, delegate: self)
        
        // 播放拍照音效
        AudioServicesPlaySystemSound(SystemSoundID(1108))
    }
    
    private func requestCameraPermission() {
        AVCaptureDevice.requestAccess(for: .video) { [weak self] granted in
            if granted {
                self?.startCaptureSession()
            } else {
                // 处理用户拒绝权限的情况
                DispatchQueue.main.async {
                    self?.setupCameraPermissionDenied()
                }
            }
        }
    }
    
    // MARK: - 开始扫码 / 结束扫码
    private func startRunningAndAnimation() {
        let starus = AVCaptureDevice.authorizationStatus(for: .video)
        switch starus {
        case .authorized:
            startCaptureSession()
        case.notDetermined:
            requestCameraPermission()
        case.denied, .restricted:
            setupCameraPermissionDenied()
        @unknown default:
            break
        }
    }
    
    private func startCaptureSession() {
        guard let captureSession = captureSession, !captureSession.isRunning else { return }
        
        // 放在后台线程中执行
        DispatchQueue.global(qos: .userInitiated).async {
            captureSession.startRunning()
        }
        
        DispatchQueue.main.async {[weak self] in
            self?.startScanLineAnimation()
        }
    }
    
    private func stopCaptureSession() {
        guard let captureSession = captureSession, captureSession.isRunning else { return }
        
        DispatchQueue.global(qos: .userInitiated).async {
            captureSession.stopRunning()
        }
        
        DispatchQueue.main.async {[weak self] in
            self?.stopScanLineAnimation()
        }
    }
    
    // MARK: - Animation Methods
    private func startScanLineAnimation() {
        guard !isAnimating else { return } // 检查动画是否已经启动
        
        scanLineAnimation = CABasicAnimation(keyPath: "transform.translation.y")
        scanLineAnimation.fromValue = 0
        scanLineAnimation.toValue = view.bounds.height * 0.6
        scanLineAnimation.duration = 3.0
        scanLineAnimation.repeatCount = .infinity
        scanLineAnimation.autoreverses = true
        scanImageView.layer.add(scanLineAnimation, forKey: "scanLineAnimation")
        isAnimating = true // 标记动画已启动
    }
    
    private func stopScanLineAnimation() {
        scanImageView.layer.removeAnimation(forKey: "scanLineAnimation")
        isAnimating = false
    }
    
    // MARK: - 扫码代理
    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        // 检查是否有扫描结果
        guard let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject,
              let stringValue = metadataObject.stringValue else {
            return
        }
        
        // 停止扫描
        stopCaptureSession()
        
        // 播放提示音和震动
        AudioServicesPlaySystemSound(SystemSoundID(1000))  // 添加系统提示音
        AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))  // 保留震动
        
        // TODO: 处理扫描到的发票二维码数据
        print("扫描结果：\(stringValue)")
    }
}

//MARK: - 拍照回调
extension ScanViewController: AVCapturePhotoCaptureDelegate {
    func photoOutput(_ output: AVCapturePhotoOutput,
                     didFinishProcessingPhoto photo: AVCapturePhoto,
                     error: Error?) {
        
        // 错误处理
        if let error = error {
            print("拍照处理错误: \(error.localizedDescription)")
            return
        }
        // 获取图片数据
        guard let imageData = photo.fileDataRepresentation(),
              let image = UIImage(data: imageData) else {
            print("无法获取照片数据")
            return
        }
        
        // 创建预览视图
        let previewView = UIView(frame: self.view.bounds)
        previewView.backgroundColor = .black
        view.addSubview(previewView)
        previewView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        let imageView = UIImageView(image: image)
        imageView.contentMode = .scaleAspectFit
        previewView.addSubview(imageView)
        imageView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        // 添加确认和重拍按钮
        let confirmButton = UIButton(type: .system)
        confirmButton.setTitle("确认", for: .normal)
        confirmButton.backgroundColor = .systemBlue
        confirmButton.setTitleColor(.white, for: .normal)
        confirmButton.addTarget(self, action: #selector(confirmPhoto), for: .touchUpInside)
        
        let retakeButton = UIButton(type: .system)
        retakeButton.setTitle("重拍", for: .normal)
        retakeButton.backgroundColor = .systemGray
        retakeButton.setTitleColor(.white, for: .normal)
        retakeButton.addTarget(self, action: #selector(retakePhoto), for: .touchUpInside)
        
         previewView.addSubview(confirmButton)
        previewView.addSubview(retakeButton)
        
        // 设置按钮约束
        confirmButton.snp.makeConstraints { make in
            make.bottom.equalTo(view.safeAreaLayoutGuide).offset(-20)
            make.trailing.equalToSuperview().offset(-20)
            make.width.equalTo(100)
            make.height.equalTo(44)
        }
        
        retakeButton.snp.makeConstraints { make in
            make.bottom.equalTo(view.safeAreaLayoutGuide).offset(-20)
            make.leading.equalToSuperview().offset(20)
            make.width.equalTo(100)
            make.height.equalTo(44)
        }
    }
    
    @objc private func confirmPhoto() {
        // TODO: 处理确认照片逻辑
        removePreview()
    }
    
    @objc private func retakePhoto() {
        removePreview()
        takePhoto() // 重新拍照
    }
    
    private func removePreview() {
        view.subviews.last?.removeFromSuperview()
    }
}
